﻿using System.Collections.Generic;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;
using PowerBooking.RSE.Contract.Contracts;
using PowerBooking.RSE.Contract.Enums;
using PowerBooking.RSE.Domain.Factories;
using PowerBooking.RSE.Domain.Models;
using PowerBooking.RSE.IRepository;
using System;
using System.Linq;
using PowerBooking.RSE.Utility.Helpers;
using System.Threading.Tasks;
using PowerBooking.RSE.Domain.Behaviors;

namespace PowerBooking.RSE.Domain.Services
{
    /// <summary>
    /// 餐厅蜘蛛引擎服务
    /// </summary>
    [ServiceContract]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
    [ErrorHandlerBehavior]
    public class RestaurantSpiderEngineService : Service
    {
        public RestaurantSpiderEngineService(IUnitOfWork unitOfWork)
            : base(unitOfWork)
        {
            SpiderMonitorStaticFactory.CreateSpiderMonitorDictionary();
        }

        /// <summary>
        /// 创建蜘蛛
        /// </summary>
        /// <param name="name"></param>
        /// <param name="url"></param>
        /// <returns></returns>
        [WebInvoke(UriTemplate = "CreateSpider", RequestFormat = WebMessageFormat.Json)]
        public void CreateSpider(CreateSpiderRequest request)
        {
            SpiderFactory.CreateSpider(request.Name, request.Url);
        }

        /// <summary>
        /// 查询蜘蛛
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [WebInvoke(UriTemplate = "QuerySpider", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
        public QuerySpiderResponse QuerySpider(QuerySpiderRequest request)
        {
            var response = new QuerySpiderResponse();
            var spider = SpiderFactory.QuerySpiderBySpiderID(request.SpiderID);
            if (spider != null)
            {
                spider.InitCities(CityFactory.GetCitiesBySpiderID(request.SpiderID));
                Parallel.For(0, spider.Cities.Count, (i) => { spider.Cities[i].InitFilters(FilterFactory.GetFiltersByCityID(spider.Cities[i].CityID)).InitRestaurants(RestaurantFactory.GetRestaurantsByCityID(spider.Cities[i].CityID)); });
                response.Spider = ModelToDTO.Spider(spider);
            }
            return response;
        }

        /// <summary>
        /// 捕获餐厅
        /// </summary>
        [WebGet(UriTemplate = "CaptureRestaurant", RequestFormat = WebMessageFormat.Json)]
        public void CaptureRestaurant()
        {
            CaptureRestaurantRequest request = new CaptureRestaurantRequest() { SpiderID = 1 };
            var spiderMonitor = SpiderMonitorStaticFactory.GetSpiderMonitor(request.SpiderID);
            if (spiderMonitor.SpiderStatus == SpiderStatusEnum.Stop)
            {
                Action action = new Action(delegate()
                {
                    try
                    {
                        spiderMonitor.UpdateStatus(SpiderStatusEnum.Running);
                        var spider = SpiderFactory.QuerySpiderBySpiderID(request.SpiderID);
                        spider.InitCities(CityFactory.CreateCities(request.SpiderID, spider.Url));
                        UnitOfWork.Save();
                        spiderMonitor.Update(spider.Cities.Count, 0, 0);
                        for (var c = 0; c < spider.Cities.Count; c++)
                        {
                            var filters = FilterFactory.CreateFilters(request.SpiderID, spider.Cities[c].CityID, spider.Cities[c].Url);
                            spider.Cities[c].InitFilters(filters);
                            spiderMonitor.Update(0, filters.Count, 0);
                        }
                        UnitOfWork.Save();
                        for (var c = 0; c < spider.Cities.Count; c++)
                        {
                            if (SpiderMonitorStaticFactory.GetSpiderMonitor(request.SpiderID).SpiderStatus != SpiderStatusEnum.Stop)
                            {
                                for (var f = 0; f < spider.Cities[c].Filters.Count; f++)
                                {
                                    if (SpiderMonitorStaticFactory.GetSpiderMonitor(request.SpiderID).SpiderStatus != SpiderStatusEnum.Stop)
                                    {
                                        var restaurantsPart = RestaurantFactory.CreateRestaurants(request.SpiderID, spider.Cities[c].CityID, spider.Cities[c].Filters[f].FilterID, spider.Cities[c].Url, spider.Cities[c].Filters[f].Url);
                                        spiderMonitor.Update(0, 0, restaurantsPart.Count);
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }
                            }
                            else
                            {
                                break;
                            }
                        }
                        UnitOfWork.Save();
                        spiderMonitor.UpdateError(null);
                    }
                    catch (Exception exception)
                    {
                        spiderMonitor.UpdateError(exception);
                    }
                });
                action.BeginInvoke(null, null);
            }
        }

        /// <summary>
        /// 根据蜘蛛ID查询捕获进度
        /// </summary>
        /// <param name="spiderID"></param>
        /// <returns></returns>
        [WebGet(UriTemplate = "QueryCaptureProcessBySpiderID/{SpiderID}", ResponseFormat = WebMessageFormat.Json)]
        public QueryCaptureProcessResponse QueryCaptureProcessBySpiderID(string spiderID)
        {
            var spiderMonitor = SpiderMonitorStaticFactory.GetSpiderMonitor(long.Parse(spiderID));
            return new QueryCaptureProcessResponse()
            {
                Cities = spiderMonitor.Cities,
                Filters = spiderMonitor.Filters,
                Restaurants = spiderMonitor.Restaurants,
                SpiderStatus = spiderMonitor.SpiderStatus,
                Exception = spiderMonitor.Exception == null ? string.Empty : spiderMonitor.Exception.Message + "|" + spiderMonitor.Exception.StackTrace + "|" + spiderMonitor.Exception.Source
            };
        }

        /// <summary>
        /// 根据蜘蛛ID停止捕获
        /// </summary>
        [WebGet(UriTemplate = "StopCaptureBySpiderID/{SpiderID}", ResponseFormat = WebMessageFormat.Json)]
        public void StopCaptureBySpiderID(string spiderID)
        {
            var spiderMonitor = SpiderMonitorStaticFactory.GetSpiderMonitor(long.Parse(spiderID));
            spiderMonitor.UpdateStatus(SpiderStatusEnum.Stop);
        }
    }
}
